import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'

// 是否正在刷新的标记 使用 isRefreshing 标记避免多个请求同时刷新 token
let isRefreshing = false
// 重试队列，每一项将是一个待执行的函数形式 
let retryRequests = []

const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  timeout: 5000
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 从 localStorage 获取 token
    const token = localStorage.getItem('authenticationToken')
    if (token) {
      // 设置统一的请求头
      config.headers.Authorization = token;
    }
    return config
  },
  error => {
    console.error('请求错误：', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    return response
  },
  async error => {
    const originalRequest = error.config
    
    // 如果响应码是 401 并且没有重试过
    if (error.response && error.response.status === 401 && !originalRequest._retry) {
      // 如果当前没有在刷新
      if (!isRefreshing) {
        isRefreshing = true
        originalRequest._retry = true
        
        try {
          // 尝试刷新 token
          const refreshToken = localStorage.getItem('refurbishToken')
          
          if (!refreshToken) {
            // 没有刷新 token，直接跳转登录页
            ElMessage.error('登录已过期，请重新登录')
            localStorage.removeItem('authenticationToken')
            localStorage.removeItem('refurbishToken')
            router.push('/')
            return Promise.reject(error)
          }
          
          // 调用刷新 token 的接口
          const response = await service({
            url: '/user/refreshToken',
            method: 'POST',
            data: {
              refreshToken: refreshToken
            },
            headers: { refreshToken: refreshToken }
          })
          
          if (response.data.code === 200) {
            console.log(response.data.data);
            // 成功刷新 token
            const newToken = response.data.data.authenticationToken
            const newRefreshToken = response.data.data.refurbishToken
            
            // 更新本地存储
            localStorage.setItem('authenticationToken', newToken)
            localStorage.setItem('refurbishToken', newRefreshToken)
            
            // 更新当前请求的 Authorization 头
            originalRequest.headers.Authorization = newToken;
            
            // 处理队列中的所有请求   维护 retryRequests 队列，存储等待 token 刷新的请求
            retryRequests.forEach(cb => cb(newToken))
            retryRequests = []
            
            // 发送原始请求
            return service(originalRequest)
          } else {
            // 刷新失败，跳转登录页
            ElMessage.error('刷新 token 失败，请重新登录')
            localStorage.removeItem('authenticationToken')
            localStorage.removeItem('refurbishToken')
            router.push('/')
            return Promise.reject(error)
          }
        } catch (refreshError) {
          // 刷新 token 请求异常
          console.error('刷新 token 失败:', refreshError)
          localStorage.removeItem('authenticationToken')
          localStorage.removeItem('refurbishToken')
          ElMessage.error('登录已过期，请重新登录')
          router.push('/')
          return Promise.reject(refreshError)
        } finally {
          isRefreshing = false
        }
      } else {
        // 刷新 token 期间，将请求缓存起来  刷新成功后自动重试所有队列中的请求
        return new Promise(resolve => {
          retryRequests.push(token => {
            originalRequest.headers.Authorization = token;
            resolve(service(originalRequest))
          })
        })
      }
    }
    
    // 其他错误
    if (error.response && error.response.data) {
      ElMessage.error(error.response.data.message || '请求失败')
    } else {
      ElMessage.error('网络错误，请稍后重试')
    }
    
    return Promise.reject(error)
  }
)

export default service